package edu.unlv.cs.ladders.entities;

import edu.unlv.cs.ladders.entities.BaseEntity;
import javax.persistence.Entity;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.tostring.RooToString;
import org.springframework.roo.addon.entity.RooEntity;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.validation.constraints.NotNull;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.format.annotation.DateTimeFormat;
import edu.unlv.cs.ladders.entities.Tag;

@Entity
@RooJavaBean
@RooToString
@RooEntity(finders = { "findTournamentsByClosed", "findTournamentsByClosedAndEndDateLessThan" })
public class Tournament extends BaseEntity {

    private static final long serialVersionUID = 1L;

    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(style = "S-")
    private Calendar startDate;

    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(style = "S-")
    private Calendar endDate;

    @OneToMany
    private Set<Team> teams;

    @ManyToMany
    private Set<Tag> tags;

    private Boolean closed = Boolean.FALSE;

    private String note;

    public String getName() {
        StringBuffer name = new StringBuffer();
        DateFormat dateFormat = new SimpleDateFormat("yyyy", LocaleContextHolder.getLocale());
        name.append(dateFormat.format(this.startDate.getTime()));
        List<Tag> tags = new ArrayList<Tag>(this.tags);
        Collections.sort(tags);
        if (tags != null) {
            for (Tag tag : tags) {
                name.append(' ');
                name.append(tag);
            }
        }
        return name.toString();
    }

    public List<Team> getTeamsOrderedByRank() {
        List<Team> orderedTeams = new ArrayList<Team>(teams);
        Collections.sort(orderedTeams, new Comparator<Team>() {

            public int compare(Team o1, Team o2) {
                int compare = 0;
                if (o1.getRank() < o2.getRank()) {
                    compare = -1;
                } else if (o1.getRank() > o2.getRank()) {
                    compare = 1;
                }
                return compare;
            }
        });
        return orderedTeams;
    }

    public String toString() {
        return this.getName();
    }

    public boolean isOpen() {
        return !closed;
    }

    public void addTeam(Team team) {
        if (!getTeams().contains(team)) {
            getTeams().add(team);
            merge();
        }
    }

    public void addTag(Tag tag) {
        if (!getTags().contains(tag)) {
            getTags().add(tag);
            merge();
        }
    }

    public Set<Team> getTeams() {
        if (this.teams == null) {
            this.teams = new HashSet<Team>();
        }
        return teams;
    }

    public Set<Tag> getTags() {
        if (this.tags == null) {
            this.tags = new HashSet<Tag>();
        }
        return tags;
    }

    public Team findTeamWithMember(Participant member) {
        Team team = null;
        for (Team currentTeam : getTeams()) {
            Set<Participant> members = currentTeam.getMembers();
            if (members != null && members.contains(member)) {
                team = currentTeam;
            }
        }
        return team;
    }
}
